﻿using AutoMapper;
using Microsoft.EntityFrameworkCore;
using QMERP.Domain.Dtos;
using QMERP.Domain.Entities;
using QMERP.Infrastructure.CustomException;
using QMERP.Infrastructure.EFCore;
using QMERP.Infrastructure.EFCore.Extensions;
using QMERP.Infrastructure.Extensions;

namespace QMERP.Application.Services
{
    public class DictionaryService : IDictionaryService
    {
        private readonly QMERPDbContext _db;
        private readonly IMapper _mapper;
        public DictionaryService(QMERPDbContext db, IMapper mapper)
        {
            _db = db;
            _mapper = mapper;
        }
        /// <summary>
        /// 字典列表
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<PageResponse<DictionaryResponse>> Query(PageRequest<DictionaryRequest> request)
        {
            var response = new PageResponse<DictionaryResponse>();
            var query = Where(request);
            var list = await query.Paging(request.PageIndex, request.PageSize).ToListAsync();
            response.TotalCount = await query.CountAsync();
            response.PageIndex = request.PageIndex;
            response.PageSize = request.PageSize;
            response.List = _mapper.Map<List<DictionaryResponse>>(list);
            return response;
        }
        /// <summary>
        /// 获取id的字典详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<DictionaryResponse> Detail(long id)
        {
            var model = await _db.Dictionary.FindByIdAsync(id);
            return _mapper.Map<DictionaryResponse>(model);
        }
        /// <summary>
        /// 字典保存
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        /// <exception cref="ApiException"></exception>
        public async Task Save(DictionarySaveRequest request)
        {
            if (await _db.Dictionary.AnyAsync(x => x.Value == request.Value && x.Id != request.Id && x.DictionaryCategoryId == request.DictionaryCategoryId))
                throw new ApiException("字典值已存在!");
            if (await _db.Dictionary.AnyAsync(x => x.Name == request.Name && x.Id != request.Id && x.DictionaryCategoryId == request.DictionaryCategoryId))
                throw new ApiException("字典名称已存在!");
            if (request.Id == null)
            {
                Dictionary model = _mapper.Map<Dictionary>(request);
                await _db.Dictionary.AddAsync(model);
            }
            else
            {
                Dictionary? model = await _db.Dictionary.FindByIdAsync(request.Id.Value);
                if (model == null)
                    throw new ApiException("字典不存在!");
                model.Name = request.Name;
                model.Value = request.Value;
                model.Sort = request.Sort;
                model.Remark = request.Remark;
            }
            await _db.SaveChangesAsync();
        }
        /// <summary>
        /// 获取category的字典集合
        /// </summary>
        /// <param name="category"></param>
        /// <returns></returns>
        public async Task<List<DictionaryComboBoxItemResponse>> GetComboBox(string category)
        {
            var dictionaries = await _db.Dictionary.Include(x => x.DictionaryCategory).Where(x => x.DictionaryCategory!.Category == category).OrderBy(x => x.Sort).ToListAsync();
            List<DictionaryComboBoxItemResponse> comboBoxItems = new();
            foreach (var dictionarie in dictionaries)
            {
                DictionaryComboBoxItemResponse comboBoxItem = new()
                {
                    Name = dictionarie.Name,
                    Value = dictionarie.Value,
                };
                comboBoxItems.Add(comboBoxItem);
            }
            return comboBoxItems;
        }
        /// <summary>
        /// 获取组合列表(可用于下拉框,复选框,单选框)
        /// </summary>
        /// <returns></returns>
        public async Task<List<DictionaryComboBoxResponse>> GetComboBoxs()
        {
            var dictionaries = await _db.Dictionary.ToListAsync();
            var categorys = await _db.DictionaryCategory.ToListAsync();
            List<DictionaryComboBoxResponse> comboBoxs = new();
            foreach (var category in categorys)
            {
                var list = dictionaries.Where(x => x.DictionaryCategoryId == category.Id).OrderBy(x => x.Sort).ToList();
                if (list.Count > 0)
                {
                    List<DictionaryComboBoxItemResponse> comboBoxItems = new();
                    foreach (var l in list)
                    {
                        DictionaryComboBoxItemResponse comboBoxItem = new()
                        { 
                            Name = l.Name,
                            Value = l.Value,
                        };
                        comboBoxItems.Add(comboBoxItem);
                    }    

                    DictionaryComboBoxResponse comboBox = new()
                    {
                        Category = category.Category,
                        ComboBoxItems = comboBoxItems
                    };
                    comboBoxs.Add(comboBox);
                }
            }
            return comboBoxs;

        }

        private IQueryable<Dictionary> Where(PageRequest<DictionaryRequest> request)
        {
            IQueryable<Dictionary> query = _db.Dictionary.Where(x => x.DictionaryCategoryId == request.Query.DictionaryCategoryId);
            if (!request.Query.Name.IsNullOrWhiteSpace())
            {
                query = query.Where(x => x.Name.Contains(request.Query.Name!));
            }
            if (!request.Query.Value.IsNullOrWhiteSpace())
            {
                query = query.Where(x => x.Value.Contains(request.Query.Value!));
            }
            return query.OrderByDescending(x => x.CreatedOn);
        }
    }
}
